package com.xxl.job.admin.rest;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibm.risk.common.rest.RestService;
import com.ibm.risk.common.vo.PagedQueryResult;
import com.xxl.job.admin.core.model.JobInfo;
import com.xxl.job.admin.core.model.JobLog;
import com.xxl.job.admin.dao.IJobGroupDao;
import com.xxl.job.admin.dao.IJobInfoDao;
import com.xxl.job.admin.dao.IJobLogDao;
import com.xxl.job.core.biz.ExecutorBiz;
import com.xxl.job.core.biz.model.LogResult;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.rpc.netcom.NetComClientProxy;

/**
 * index controller
 * 
 * @author xuxueli 2015-12-19 16:13:16
 */
@RestService
@Path("/joblog")
public class JobLogResource {

	@Inject
	IJobGroupDao xxlJobGroupDao;
	@Inject
	IJobInfoDao xxlJobInfoDao;
	@Inject
	IJobLogDao xxlJobLogDao;

	@Path("/jobGroups/{jobGroup}")
	@GET
	public ReturnT<List<JobInfo>> listJobByGroup(@PathParam("jobGroup") Long jobGroup) {
		List<JobInfo> list = xxlJobInfoDao.getJobsByGroup(jobGroup);
		return new ReturnT<List<JobInfo>>(list);
	}

	@Path("/pageList")
	@GET
	public Map<String, Object> pageList(@QueryParam("start") int start, @QueryParam("length") int length,
		@QueryParam("jobGroup") Long jobGroup, @QueryParam("jobId") Long jobId, @QueryParam("filterTime") String filterTime) {
		if (length == 0) {
			length = 10;
		}
		// parse param
		Date triggerTimeStart = null;
		Date triggerTimeEnd = null;
		if (StringUtils.isNotBlank(filterTime)) {
			String[] temp = filterTime.split(" - ");
			if (temp != null && temp.length == 2) {
				try {
					triggerTimeStart = DateUtils.parseDate(temp[0], new String[] { "yyyy-MM-dd HH:mm:ss" });
					triggerTimeEnd = DateUtils.parseDate(temp[1], new String[] { "yyyy-MM-dd HH:mm:ss" });
				} catch (ParseException e) {
				}
			}
		}

		// page query
		PagedQueryResult<JobLog> rst = xxlJobLogDao.pageList(start / length + 1, length, jobGroup, jobId, triggerTimeStart, triggerTimeEnd);
		List<JobLog> list = rst.getDatas();
		int list_count = rst.getRecordCount();

		// package result
		Map<String, Object> maps = new HashMap<String, Object>();
		maps.put("recordsTotal", list_count); // 总记录数
		maps.put("recordsFiltered", list_count); // 过滤后的总记录数
		maps.put("data", list); // 分页列表
		return maps;
	}

	@Path("/logDetailCat")
	@GET
	public ReturnT<LogResult> logDetailCat(@QueryParam("executorAddress") String executorAddress,
		@QueryParam("triggerTime") long triggerTime,
		@QueryParam("logId") Long logId, @QueryParam("fromLineNum") int fromLineNum) {
		try {
			ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, executorAddress).getObject();
			ReturnT logResult = executorBiz.log(triggerTime, logId, fromLineNum);
			if (logResult.getContent() != null) {
				ObjectMapper om = new ObjectMapper();
				String json = om.writeValueAsString(logResult.getContent());
				logResult.setContent(om.readValue(json, LogResult.class));

			}
			// is end
			LogResult content = (LogResult) logResult.getContent();
			if (content != null && content.getFromLineNum() > content.getToLineNum()) {
				JobLog jobLog = xxlJobLogDao.load(logId);
				if (jobLog.getHandleCode() != null) {
					content.setEnd(true);
				}
			}

			return logResult;
		} catch (Exception e) {
			e.printStackTrace();
			return new ReturnT<LogResult>(ReturnT.FAIL_CODE, e.getMessage());
		}
	}

	@Path("/logKill/{id}")
	@POST
	public ReturnT<String> logKill(@PathParam("id") Long id) {
		// base check
		JobLog log = xxlJobLogDao.load(id);
		JobInfo jobInfo = xxlJobInfoDao.loadById(log.getJobId());
		if (jobInfo == null) {
			return new ReturnT<String>(500, "参数异常");
		}
		if (ReturnT.SUCCESS_CODE != log.getTriggerCode()) {
			return new ReturnT<String>(500, "调度失败，无法终止日志");
		}

		// request of kill
		ExecutorBiz executorBiz = null;
		try {
			executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, log.getExecutorAddress()).getObject();
		} catch (Exception e) {
			e.printStackTrace();
			return new ReturnT<String>(500, e.getMessage());
		}
		ReturnT<String> runResult = executorBiz.kill(jobInfo.getId());

		if (ReturnT.SUCCESS_CODE == runResult.getCode()) {
			log.setHandleCode(ReturnT.FAIL_CODE + "");
			log.setHandleMsg("人为操作主动终止:" + (runResult.getMsg() != null ? runResult.getMsg() : ""));
			log.setHandleTime(new Date());
			xxlJobLogDao.updateHandleInfo(log);
			return new ReturnT<String>(runResult.getMsg());
		} else {
			return new ReturnT<String>(500, runResult.getMsg());
		}
	}
}
